﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Castle.Windsor;

namespace CodeRepositoryConsole.DesignPattern
{
    /**
     * http://blog.ploeh.dk/2012/03/15/ImplementinganAbstractFactory/
     */

    public class Order
    {
        public string OrderCode { get; set; }
    }

    public interface IChannel { }

    public interface IOrderShipper
    {
        void Ship(Order order);
    }

    /// <summary>
    /// class that factory need to create
    /// </summary>
    public class OrderShipper2 : IOrderShipper
    {
        private readonly IChannel channel;

        public OrderShipper2(IChannel channel)
        {
            if (channel == null)
                throw new ArgumentNullException("channel");
            this.channel = channel;
        }

        public void Ship(Order order)
        {

        }
    }

    interface IOrderShipperFactory
    {
        IOrderShipper Create();
    }

    /// <summary>
    /// Manually Coded Factory
    /// </summary>
    public class ManualOrderShipperFactory : IOrderShipperFactory
    {
        private readonly IChannel channel;

        public ManualOrderShipperFactory(IChannel channel)
        {
            if (channel == null)
                throw new ArgumentNullException("channel");
            this.channel = channel;
        }

        public IOrderShipper Create()
        {
            return new OrderShipper2(channel);
        }
    }

    /// <summary>
    /// Container-based Factory
    /// </summary>
    public class ContainerFactory : IOrderShipperFactory
    {
        private IWindsorContainer container;

        public ContainerFactory(IWindsorContainer container)
        {
            if (container == null)
                throw new ArgumentNullException(nameof(container));

            this.container = container;
        }

        public IOrderShipper Create()
        {
            return this.container.Resolve<IOrderShipper>();
        }
    }

}
